package com.yc.services;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yc.bean.Cart;
import com.yc.mapper.CartMapper;
import com.yc.web.DTO.CartDTO;
import com.yc.web.DTO.ProductDTO;
import com.yc.web.clients.IdGeneratorClient;
import com.yc.web.controller.model.ResponseResult;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CartServiceImpl implements CartService {

    private final CartMapper cartMapper;
    private final IdGeneratorClient idGeneratorClient;
    private final ProductService productService;

    /**
     * 添加商品到购物车
     * @param cartDTO 购物车DTO，包含用户ID、商品ID和数量
     * @return 包含商品信息的购物车DTO
     */
    @Override
    @Transactional
    public CartDTO addToCart(CartDTO cartDTO) {
        // 1. 查询商品信息
        ProductDTO product = productService.getProductById(cartDTO.getProductId());
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        // 2. 检查是否已存在购物车记录
        LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Cart::getUserId, cartDTO.getUserId())
                .eq(Cart::getProductId, cartDTO.getProductId());

        Cart existingCart = cartMapper.selectOne(queryWrapper);

        if (existingCart != null) {
            // 3. 已存在则更新数量
            existingCart.setQuantity(existingCart.getQuantity() + cartDTO.getQuantity());
            cartMapper.updateById(existingCart);

            // 返回包含商品信息的DTO
            return convertToDTO(existingCart, product);
        } else {
            // 4. 不存在则新增记录
            ResponseResult rr = this.idGeneratorClient.getNextId();
            if (rr.getCode() != 1) {
                throw new RuntimeException("购物车ID生成失败");
            }

            Cart cart = new Cart();
            cart.setCartId(Long.parseLong(rr.getData().toString()));
            cart.setUserId(cartDTO.getUserId());
            cart.setProductId(cartDTO.getProductId());
            cart.setQuantity(cartDTO.getQuantity());

            int result = cartMapper.insert(cart);
            if (result > 0) {
                return convertToDTO(cart, product);
            } else {
                throw new RuntimeException("添加到购物车失败");
            }
        }
    }

    /**
     * 根据用户ID查询购物车
     * @param userId 用户ID
     * @return 购物车DTO列表
     */
    @Override
    public List<CartDTO> getCartByUserId(Long userId) {
        LambdaQueryWrapper<Cart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Cart::getUserId, userId);

        List<Cart> carts = cartMapper.selectList(queryWrapper);

        return carts.stream().map(cart -> {
            ProductDTO product = productService.getProductById(cart.getProductId());
            return convertToDTO(cart, product);
        }).collect(Collectors.toList());
    }

    // 实体转DTO（包含商品信息）
    private CartDTO convertToDTO(Cart cart, ProductDTO product) {
        CartDTO dto = new CartDTO();
        // 复制购物车基础信息
        BeanUtils.copyProperties(cart, dto);

        // 填充商品信息
        if (product != null) {
            dto.setProductName(product.getProductName());
            dto.setPrice(product.getPrice());
            dto.setMainImage(product.getMainImage());
        }

        return dto;
    }

    /**
     * 从购物车移除商品
     * DELETE /cart/{cartId}
     * @param cartId 购物车项ID
     * @return 删除结果
     */
    @Override
    @Transactional
    public boolean removeFromCart(Long cartId) {
        // 1. 先查询购物车项是否存在
        Cart cart = cartMapper.selectById(cartId);
        if (cart == null) {
            throw new RuntimeException("购物车项不存在");
        }

        // 2. 删除购物车项
        int result = cartMapper.deleteById(cartId);
        return result > 0;
    }

    /**
     * 根据增量更新购物车数量
     * @param cartId 购物车项ID
     * @param delta 增量（正数表示增加，负数表示减少）
     * @return 更新后的购物车DTO
     */
    @Override
    @Transactional
    public CartDTO updateCartByDelta(Long cartId, Integer delta) {
        // 1. 参数校验
        if (delta == null) {
            throw new RuntimeException("增量值不能为空");
        }

        // 2. 查询购物车项
        Cart cart = cartMapper.selectById(cartId);
        if (cart == null) {
            throw new RuntimeException("购物车项不存在");
        }

        // 3. 计算新数量
        int newQuantity = cart.getQuantity() + delta;
        return updateCartQuantityInternal(cart, newQuantity);
    }

    /**
     * 设置购物车绝对数量
     * @param cartId 购物车项ID
     * @param quantity 新的绝对数量
     * @return 更新后的购物车DTO
     */
    @Override
    @Transactional
    public CartDTO updateCartToQuantity(Long cartId, Integer quantity) {
        // 1. 参数校验
        if (quantity == null) {
            throw new RuntimeException("数量值不能为空");
        }
        if (quantity < 0) {
            throw new RuntimeException("商品数量不能小于0");
        }

        // 2. 查询购物车项
        Cart cart = cartMapper.selectById(cartId);
        if (cart == null) {
            throw new RuntimeException("购物车项不存在");
        }

        return updateCartQuantityInternal(cart, quantity);
    }

    /**
     * 内部公共方法 - 更新购物车数量
     */
    private CartDTO updateCartQuantityInternal(Cart cart, int newQuantity) {
        // 1. 查询商品信息
        ProductDTO product = productService.getProductById(cart.getProductId());
        if (product == null) {
            throw new RuntimeException("商品不存在或已下架");
        }

        // 2. 如果新数量为0，删除该商品
        if (newQuantity == 0) {
            removeFromCart(cart.getCartId());
            return null; // 返回null表示商品已删除
        }

        // 3. 更新数量
        cart.setQuantity(newQuantity);
        int result = cartMapper.updateById(cart);
        if (result <= 0) {
            throw new RuntimeException("更新购物车数量失败");
        }

        // 4. 返回更新后的DTO
        return convertToDTO(cart, product);
    }
}